//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <PowerInc.h>
#include <TimeManager.h>

_ELASTOS_NAMESPACE_USING

static IThread * g_pTimerThread=NULL;
static IDeviceDriver * g_pTimer = NULL;
static POWER_THREAD_TYPE NotiProc(void * pArg)
{
    while (1) {
        MemoryBuf_<8> ebbData;
        ECode ec = g_pEventQueues->Read(EVENT_POWER, 0,
                &ebbData, NULL);
        if (FAILED(ec)) {
            DebugPrint("No Data\n");
            continue;
        }
        unsigned long * data=(unsigned long *)ebbData.GetPayload();
        //DebugPrint("the data %d,%d\n",data[0],data[1]);
        TimerCallBackProc func=(TimerCallBackProc)data[0];
        assert(NULL != func);
        void * arg=(void *)data[1];
        func(arg);
    }
    return 0;
}

ECode PowerCreateTimer(int *pTimerID, unsigned long Resolution,
    unsigned Interval, TimerCallBackProc pCallbackProc, void * pvArg)
{
    MemoryBuf ebbHandleOut((Byte *)pTimerID, 4, 4);
    MemoryBuf_<sizeof(TimerInfo)> ebbHandleIn;
    assert(NULL != pCallbackProc);

    TimerInfo ti;
    ti.eType=EVENT_POWER;
    ti.pCallbackProc=pCallbackProc;
    ti.pvArg=pvArg;
    ti.Resolution=Resolution;
    ti.Interval=Interval;
    ebbHandleIn.Copy((Byte *)&ti, sizeof(ti));
    ECode ec=NOERROR;
    if (NULL == g_pTimer) {
        ec = PowerFindService(L"device:timer1",(IInterface **)&g_pTimer);
        if (FAILED(ec)) return ec;
    }
    ec = g_pTimer->Control(11, ebbHandleIn, &ebbHandleOut, NULL );
    if (FAILED(ec)) return ec;
    assert(*pTimerID >= 0);
    DebugOut(DebugPrint("in create timer id%d\n",*pTimerID);)
    if (NULL == g_pTimerThread)
    {
        if (NULL==g_pEventQueues) {
            ec = PowerFindService(
                    L"device:eq0", (IInterface **)&g_pEventQueues);
            if (FAILED(ec)) return ec;
        }
        ec = PowerCreateThread(NotiProc, NULL, POWER_THREAD_FLAG,
            ThreadPriorityRank_Normal,&g_pTimerThread);
        if (FAILED(ec)) return ec;
    }
    return ec;
}

ECode PowerKillTimer(int TimerID)
{
    if (NULL == g_pTimer) return E_ACCESS_DENIED;
    MemoryBuf_<4> ebbHandle;
    ebbHandle.Copy((Byte *)&TimerID, sizeof(int));
    ECode ec = g_pTimer->Control(
                12, ebbHandle, NULL, NULL );
    return ec;
}

ECode PowerStartTimer(int TimerID)
{
    if (NULL == g_pTimer) return E_ACCESS_DENIED;
    MemoryBuf_<4> ebbHandle;
    ebbHandle.Copy((Byte *)&TimerID, sizeof(int));
    ECode ec = g_pTimer->Control(
                14, ebbHandle, NULL, NULL );
    return ec;
}

ECode PowerReStartTimer(int TimerID, int Interval)
{
    if (NULL == g_pTimer) return E_ACCESS_DENIED;
    MemoryBuf_<8> ebbParam;
    int *pParam = (int *)ebbParam.GetPayload();
    pParam[0] = TimerID;
    pParam[1] = Interval;
    ebbParam.SetUsed(8);

    ECode ec = g_pTimer->Control(
                16, ebbParam, NULL, NULL );
    return ec;
}

ECode PowerSetTimerInterval(int TimerID, int Interval)
{
    if (NULL == g_pTimer) return E_ACCESS_DENIED;
    MemoryBuf_<8> ebbParam;
    int *pParam = (int *)ebbParam.GetPayload();
    pParam[0] = TimerID;
    pParam[1] = Interval;
    ebbParam.SetUsed(8);

    ECode ec = g_pTimer->Control(
                13, ebbParam, NULL, NULL );
    return ec;
}

ECode PowerStopTimer(int TimerID)
{
    if (NULL == g_pTimer) return E_ACCESS_DENIED;
    MemoryBuf_<4> ebbHandle;
    ebbHandle.Copy((Byte *)&TimerID, sizeof(int));
    ECode ec = g_pTimer->Control(
                15, ebbHandle, NULL, NULL );
    return ec;
}

ECode PowerShortTimer(int TimerID)
{
    if (NULL == g_pTimer) return E_ACCESS_DENIED;
    MemoryBuf_<4> ebbHandle;
    ebbHandle.Copy((Byte *)&TimerID, sizeof(int));
    ECode ec = g_pTimer->Control(
                17, ebbHandle, NULL, NULL );
    return ec;
}

ECode PowerGetCurrentTicks(unsigned long *pTicks)
{
    if (NULL == g_pTimer) return E_ACCESS_DENIED;
    MemoryBuf ebbData((Byte *)pTicks, 4, 4);
    ECode ec = g_pTimer->Control(
                20, NULL_MEMORYBUF, &ebbData, NULL );
    return ec;
}

ECode PowerGetLeftTime(int TimerID, unsigned long *pTimes)
{
    if (NULL == g_pTimer) return E_ACCESS_DENIED;
    MemoryBuf_<4> ebbDataIn;
    ebbDataIn.Copy((Byte *)&TimerID, sizeof(int));
    MemoryBuf ebbDataOut((Byte *)pTimes, 4, 4);
    ECode ec = g_pTimer->Control(
                18, ebbDataIn, &ebbDataOut, NULL );
    return ec;
}
